nanopyx.data.download

  1import os
  2import shutil
  3import tempfile
  4import zipfile
  5from urllib.request import ProxyHandler, build_opener, install_opener
  6
  7import numpy as np
  8import yaml
  9from gdown import download as gdrive_download
 10from onedrivedownloader import download as onedrive_download
 11from ..core.io.downloader import download
 12
 13from ..core.io.zip_image_loader import ZipTiffIterator
 14from .examples import get_path as get_examples_path
 15
 16
 17class ExampleDataManager:
 18    _base_path = get_examples_path()
 19    _temp_dir = os.path.join(tempfile.gettempdir(), "nanopyx_data")
 20    _to_download_path = None
 21
 22    def __init__(self, to_download_path: str = None):
 23        """
 24        Helper class for downloading example test data
 25
 26        :param to_download_path: path to download the data to. If to_download_path is None, a temporary directory
 27        will be created. Note that it will not be automatically deleted.
 28        :type to_download_path: str, optional
 29        :raises ValueError: If to_download_path is not None and does not exist
 30
 31        To clear downloads use self._clear_download()
 32        """
 33
 34        # Set download path
 35        if to_download_path is None:
 36            self._to_download_path = self._temp_dir
 37        else:
 38            self._to_download_path = to_download_path
 39
 40        # Lets check on how many examples we have available
 41        self._datasets = []
 42        for path in os.listdir(self._base_path):
 43            full_path = os.path.join(self._base_path, path)
 44            info_file_path = os.path.join(full_path, "info.yaml")
 45            if os.path.isdir(full_path) and os.path.exists(info_file_path):
 46                info_data = None
 47                with open(os.path.join(info_file_path), "r") as f:
 48                    # Load the YAML contents
 49                    info_data = yaml.load(f, Loader=yaml.FullLoader)
 50
 51                info = {
 52                    "info_path": info_file_path,
 53                    "thumbnail_path": os.path.join(
 54                        self._base_path, path, "thumbnail.jpg"
 55                    ),
 56                    "tiff_sequence_path": None,
 57                }
 58                tiff_sequence_path = os.path.join(
 59                    self._to_download_path, path, "tiff_sequence.zip"
 60                )
 61                if os.path.exists(tiff_sequence_path):
 62                    info["tiff_sequence_path"] = tiff_sequence_path
 63
 64                for key in info_data:
 65                    info[key] = info_data[key]
 66
 67                info["shape"] = tuple([int(v) for v in info["data_shape"].split(",")])
 68
 69                info["dtype"] = np.dtype(info["data_dtype"])
 70
 71                self._datasets.append(info)
 72
 73        # Fix agent
 74        proxy = ProxyHandler({})
 75        opener = build_opener(proxy)
 76        opener.addheaders = [
 77            (
 78                "User-Agent",
 79                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30"
 80                + " (KHTML, like Gecko) Version/10.1 Safari/603.1.30",
 81            )
 82        ]
 83        install_opener(opener)
 84
 85    def list_datasets(self) -> tuple:
 86        """
 87        :return: list of dataset labels
 88        """
 89        return sorted([dataset["label"] for dataset in self._datasets])
 90
 91    def list_datasets_nickname(self) -> tuple:
 92        """
 93        :return: list of dataset nicknames
 94        """
 95        return [(dataset["nickname"], dataset["label"]) for dataset in self._datasets]
 96
 97    def get_dataset_info(self, dataset_name: str) -> dict:
 98        """
 99        :param dataset_name: can be a dataset label or nickname
100        :type dataset_name: str
101        :return: dictionary with information about the dataset
102        """
103        for dataset in self._datasets:
104            if dataset_name in (dataset["label"], dataset["nickname"]):
105                return dataset
106        raise ValueError(f"{dataset_name} not found in example datasets")
107
108    def _download(self, url, file_path, download_type=None, unzip=False):
109        if os.path.exists(
110            file_path
111        ):  # or os.path.exists(os.path.splitext(file_path)[0]):
112            # raise Warning(f"already exists, no need to download: {file_path}")
113            return
114
115        if not os.path.exists(self._temp_dir):
116            os.mkdir(self._temp_dir)
117
118        base_path = os.path.split(file_path)[0]
119        if not os.path.exists(base_path):
120            os.mkdir(base_path)
121
122        if download_type == "onedrive":
123            onedrive_download(url, file_path, unzip=unzip, clean=True)
124        elif download_type == "gdrive":
125            gdrive_download(url, file_path, fuzzy=True, quiet=False)
126        else:
127            download(url, file_path)
128
129    def _copy_auxiliary_files(self, info: dict):
130        if not os.path.exists(self._to_download_path):
131            os.mkdir(self._to_download_path)
132
133        path = os.path.join(self._to_download_path, info["label"])
134        if not os.path.exists(path):
135            os.mkdir(path)
136
137        # thumbnail_path = os.path.join(path, "thumbnail.jpg")
138        # if not os.path.exists(thumbnail_path):
139        #    shutil.copyfile(info["thumbnail_path"], thumbnail_path)
140
141        info_path = os.path.join(path, "info.yaml")
142        if not os.path.exists(info_path):
143            shutil.copyfile(info["info_path"], info_path)
144
145    def download_tiff_sequence(self, dataset_name: str) -> str:
146        """
147        Downloads the tiff sequence and returns the path to the zip file
148
149        :param dataset_name: can be a dataset label or nickname
150        :type dataset_name: str
151        :return: path to the zip file
152        """
153        info = self.get_dataset_info(dataset_name)
154        path = os.path.join(self._to_download_path, info["label"])
155
156        file_path = os.path.join(path, "tiff_sequence.zip")
157        url = info["tiff_sequence_url"]
158        download_type = info["tiff_sequence_url_type"]
159
160        self._copy_auxiliary_files(info)
161        self._download(url, file_path, download_type)
162        info["tiff_sequence_path"] = file_path
163
164        return file_path
165
166    def is_downloaded(self, dataset_name: str) -> bool:
167        """
168        :param dataset_name: can be a dataset label or nickname
169        :type dataset_name: str
170        :return: True if the dataset is downloaded
171        """
172        info = self.get_dataset_info(dataset_name)
173        return info["tiff_sequence_path"] is not None
174
175    def get_ZipTiffIterator(
176        self, dataset_name: str, as_ndarray: bool = False
177    ) -> ZipTiffIterator:
178        """
179        Downloads the tiff sequence and returns the ZipTiffIterator
180
181        :param dataset_name: can be a dataset label or nickname
182        :type dataset_name: str
183        :param as_ndarray: if True, returns a numpy array instead of a ZipTiffIterator
184        :type as_ndarray: bool
185        :return: ZipTiffIterator or numpy array
186        """
187        self._show_citation_notice(dataset_name)
188        file_path = self.download_tiff_sequence(dataset_name)
189        try:
190            zti = ZipTiffIterator(file_path)
191        except zipfile.BadZipFile:
192            self.clear_downloads()
193            # try once more
194            file_path = self.download_tiff_sequence(dataset_name)
195            zti = ZipTiffIterator(file_path)
196        if not as_ndarray:
197            return zti
198        else:
199            arr = np.asarray(zti)
200            zti.close()
201            return arr
202
203    def get_thumbnail(self, dataset_name: str) -> str:
204        """
205        Returns the path to the thumbnail
206
207        :param dataset_name: can be a dataset label or nickname
208        :type dataset_name: str
209        :return: path to the thumbnail
210        """
211        info = self.get_dataset_info(dataset_name)
212        return info["thumbnail_path"]
213
214    def clear_downloads(self):
215        """
216        Deletes all downloaded datasets
217        """
218        if os.path.exists(self._temp_dir):
219            shutil.rmtree(self._temp_dir)
220
221    def _show_citation_notice(self, dataset_name: str):
222        info = self.get_dataset_info(dataset_name)
223        if info["reference"] not in [None, ""]:
224            print(
225                f"If you find the '{dataset_name}' dataset useful, please cite: "
226                + f"{info['reference']} - {info['reference_doi']}"
227            )
class ExampleDataManager:
 18class ExampleDataManager:
 19    _base_path = get_examples_path()
 20    _temp_dir = os.path.join(tempfile.gettempdir(), "nanopyx_data")
 21    _to_download_path = None
 22
 23    def __init__(self, to_download_path: str = None):
 24        """
 25        Helper class for downloading example test data
 26
 27        :param to_download_path: path to download the data to. If to_download_path is None, a temporary directory
 28        will be created. Note that it will not be automatically deleted.
 29        :type to_download_path: str, optional
 30        :raises ValueError: If to_download_path is not None and does not exist
 31
 32        To clear downloads use self._clear_download()
 33        """
 34
 35        # Set download path
 36        if to_download_path is None:
 37            self._to_download_path = self._temp_dir
 38        else:
 39            self._to_download_path = to_download_path
 40
 41        # Lets check on how many examples we have available
 42        self._datasets = []
 43        for path in os.listdir(self._base_path):
 44            full_path = os.path.join(self._base_path, path)
 45            info_file_path = os.path.join(full_path, "info.yaml")
 46            if os.path.isdir(full_path) and os.path.exists(info_file_path):
 47                info_data = None
 48                with open(os.path.join(info_file_path), "r") as f:
 49                    # Load the YAML contents
 50                    info_data = yaml.load(f, Loader=yaml.FullLoader)
 51
 52                info = {
 53                    "info_path": info_file_path,
 54                    "thumbnail_path": os.path.join(
 55                        self._base_path, path, "thumbnail.jpg"
 56                    ),
 57                    "tiff_sequence_path": None,
 58                }
 59                tiff_sequence_path = os.path.join(
 60                    self._to_download_path, path, "tiff_sequence.zip"
 61                )
 62                if os.path.exists(tiff_sequence_path):
 63                    info["tiff_sequence_path"] = tiff_sequence_path
 64
 65                for key in info_data:
 66                    info[key] = info_data[key]
 67
 68                info["shape"] = tuple([int(v) for v in info["data_shape"].split(",")])
 69
 70                info["dtype"] = np.dtype(info["data_dtype"])
 71
 72                self._datasets.append(info)
 73
 74        # Fix agent
 75        proxy = ProxyHandler({})
 76        opener = build_opener(proxy)
 77        opener.addheaders = [
 78            (
 79                "User-Agent",
 80                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30"
 81                + " (KHTML, like Gecko) Version/10.1 Safari/603.1.30",
 82            )
 83        ]
 84        install_opener(opener)
 85
 86    def list_datasets(self) -> tuple:
 87        """
 88        :return: list of dataset labels
 89        """
 90        return sorted([dataset["label"] for dataset in self._datasets])
 91
 92    def list_datasets_nickname(self) -> tuple:
 93        """
 94        :return: list of dataset nicknames
 95        """
 96        return [(dataset["nickname"], dataset["label"]) for dataset in self._datasets]
 97
 98    def get_dataset_info(self, dataset_name: str) -> dict:
 99        """
100        :param dataset_name: can be a dataset label or nickname
101        :type dataset_name: str
102        :return: dictionary with information about the dataset
103        """
104        for dataset in self._datasets:
105            if dataset_name in (dataset["label"], dataset["nickname"]):
106                return dataset
107        raise ValueError(f"{dataset_name} not found in example datasets")
108
109    def _download(self, url, file_path, download_type=None, unzip=False):
110        if os.path.exists(
111            file_path
112        ):  # or os.path.exists(os.path.splitext(file_path)[0]):
113            # raise Warning(f"already exists, no need to download: {file_path}")
114            return
115
116        if not os.path.exists(self._temp_dir):
117            os.mkdir(self._temp_dir)
118
119        base_path = os.path.split(file_path)[0]
120        if not os.path.exists(base_path):
121            os.mkdir(base_path)
122
123        if download_type == "onedrive":
124            onedrive_download(url, file_path, unzip=unzip, clean=True)
125        elif download_type == "gdrive":
126            gdrive_download(url, file_path, fuzzy=True, quiet=False)
127        else:
128            download(url, file_path)
129
130    def _copy_auxiliary_files(self, info: dict):
131        if not os.path.exists(self._to_download_path):
132            os.mkdir(self._to_download_path)
133
134        path = os.path.join(self._to_download_path, info["label"])
135        if not os.path.exists(path):
136            os.mkdir(path)
137
138        # thumbnail_path = os.path.join(path, "thumbnail.jpg")
139        # if not os.path.exists(thumbnail_path):
140        #    shutil.copyfile(info["thumbnail_path"], thumbnail_path)
141
142        info_path = os.path.join(path, "info.yaml")
143        if not os.path.exists(info_path):
144            shutil.copyfile(info["info_path"], info_path)
145
146    def download_tiff_sequence(self, dataset_name: str) -> str:
147        """
148        Downloads the tiff sequence and returns the path to the zip file
149
150        :param dataset_name: can be a dataset label or nickname
151        :type dataset_name: str
152        :return: path to the zip file
153        """
154        info = self.get_dataset_info(dataset_name)
155        path = os.path.join(self._to_download_path, info["label"])
156
157        file_path = os.path.join(path, "tiff_sequence.zip")
158        url = info["tiff_sequence_url"]
159        download_type = info["tiff_sequence_url_type"]
160
161        self._copy_auxiliary_files(info)
162        self._download(url, file_path, download_type)
163        info["tiff_sequence_path"] = file_path
164
165        return file_path
166
167    def is_downloaded(self, dataset_name: str) -> bool:
168        """
169        :param dataset_name: can be a dataset label or nickname
170        :type dataset_name: str
171        :return: True if the dataset is downloaded
172        """
173        info = self.get_dataset_info(dataset_name)
174        return info["tiff_sequence_path"] is not None
175
176    def get_ZipTiffIterator(
177        self, dataset_name: str, as_ndarray: bool = False
178    ) -> ZipTiffIterator:
179        """
180        Downloads the tiff sequence and returns the ZipTiffIterator
181
182        :param dataset_name: can be a dataset label or nickname
183        :type dataset_name: str
184        :param as_ndarray: if True, returns a numpy array instead of a ZipTiffIterator
185        :type as_ndarray: bool
186        :return: ZipTiffIterator or numpy array
187        """
188        self._show_citation_notice(dataset_name)
189        file_path = self.download_tiff_sequence(dataset_name)
190        try:
191            zti = ZipTiffIterator(file_path)
192        except zipfile.BadZipFile:
193            self.clear_downloads()
194            # try once more
195            file_path = self.download_tiff_sequence(dataset_name)
196            zti = ZipTiffIterator(file_path)
197        if not as_ndarray:
198            return zti
199        else:
200            arr = np.asarray(zti)
201            zti.close()
202            return arr
203
204    def get_thumbnail(self, dataset_name: str) -> str:
205        """
206        Returns the path to the thumbnail
207
208        :param dataset_name: can be a dataset label or nickname
209        :type dataset_name: str
210        :return: path to the thumbnail
211        """
212        info = self.get_dataset_info(dataset_name)
213        return info["thumbnail_path"]
214
215    def clear_downloads(self):
216        """
217        Deletes all downloaded datasets
218        """
219        if os.path.exists(self._temp_dir):
220            shutil.rmtree(self._temp_dir)
221
222    def _show_citation_notice(self, dataset_name: str):
223        info = self.get_dataset_info(dataset_name)
224        if info["reference"] not in [None, ""]:
225            print(
226                f"If you find the '{dataset_name}' dataset useful, please cite: "
227                + f"{info['reference']} - {info['reference_doi']}"
228            )
ExampleDataManager(to_download_path: str = None)
23    def __init__(self, to_download_path: str = None):
24        """
25        Helper class for downloading example test data
26
27        :param to_download_path: path to download the data to. If to_download_path is None, a temporary directory
28        will be created. Note that it will not be automatically deleted.
29        :type to_download_path: str, optional
30        :raises ValueError: If to_download_path is not None and does not exist
31
32        To clear downloads use self._clear_download()
33        """
34
35        # Set download path
36        if to_download_path is None:
37            self._to_download_path = self._temp_dir
38        else:
39            self._to_download_path = to_download_path
40
41        # Lets check on how many examples we have available
42        self._datasets = []
43        for path in os.listdir(self._base_path):
44            full_path = os.path.join(self._base_path, path)
45            info_file_path = os.path.join(full_path, "info.yaml")
46            if os.path.isdir(full_path) and os.path.exists(info_file_path):
47                info_data = None
48                with open(os.path.join(info_file_path), "r") as f:
49                    # Load the YAML contents
50                    info_data = yaml.load(f, Loader=yaml.FullLoader)
51
52                info = {
53                    "info_path": info_file_path,
54                    "thumbnail_path": os.path.join(
55                        self._base_path, path, "thumbnail.jpg"
56                    ),
57                    "tiff_sequence_path": None,
58                }
59                tiff_sequence_path = os.path.join(
60                    self._to_download_path, path, "tiff_sequence.zip"
61                )
62                if os.path.exists(tiff_sequence_path):
63                    info["tiff_sequence_path"] = tiff_sequence_path
64
65                for key in info_data:
66                    info[key] = info_data[key]
67
68                info["shape"] = tuple([int(v) for v in info["data_shape"].split(",")])
69
70                info["dtype"] = np.dtype(info["data_dtype"])
71
72                self._datasets.append(info)
73
74        # Fix agent
75        proxy = ProxyHandler({})
76        opener = build_opener(proxy)
77        opener.addheaders = [
78            (
79                "User-Agent",
80                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30"
81                + " (KHTML, like Gecko) Version/10.1 Safari/603.1.30",
82            )
83        ]
84        install_opener(opener)

Helper class for downloading example test data

Parameters
  • to_download_path: path to download the data to. If to_download_path is None, a temporary directory will be created. Note that it will not be automatically deleted.
Raises
  • ValueError: If to_download_path is not None and does not exist

To clear downloads use self._clear_download()

def list_datasets(self) -> tuple:
86    def list_datasets(self) -> tuple:
87        """
88        :return: list of dataset labels
89        """
90        return sorted([dataset["label"] for dataset in self._datasets])
Returns

list of dataset labels

def list_datasets_nickname(self) -> tuple:
92    def list_datasets_nickname(self) -> tuple:
93        """
94        :return: list of dataset nicknames
95        """
96        return [(dataset["nickname"], dataset["label"]) for dataset in self._datasets]
Returns

list of dataset nicknames

def get_dataset_info(self, dataset_name: str) -> dict:
 98    def get_dataset_info(self, dataset_name: str) -> dict:
 99        """
100        :param dataset_name: can be a dataset label or nickname
101        :type dataset_name: str
102        :return: dictionary with information about the dataset
103        """
104        for dataset in self._datasets:
105            if dataset_name in (dataset["label"], dataset["nickname"]):
106                return dataset
107        raise ValueError(f"{dataset_name} not found in example datasets")
Parameters
  • dataset_name: can be a dataset label or nickname
Returns

dictionary with information about the dataset

def download_tiff_sequence(self, dataset_name: str) -> str:
146    def download_tiff_sequence(self, dataset_name: str) -> str:
147        """
148        Downloads the tiff sequence and returns the path to the zip file
149
150        :param dataset_name: can be a dataset label or nickname
151        :type dataset_name: str
152        :return: path to the zip file
153        """
154        info = self.get_dataset_info(dataset_name)
155        path = os.path.join(self._to_download_path, info["label"])
156
157        file_path = os.path.join(path, "tiff_sequence.zip")
158        url = info["tiff_sequence_url"]
159        download_type = info["tiff_sequence_url_type"]
160
161        self._copy_auxiliary_files(info)
162        self._download(url, file_path, download_type)
163        info["tiff_sequence_path"] = file_path
164
165        return file_path

Downloads the tiff sequence and returns the path to the zip file

Parameters
  • dataset_name: can be a dataset label or nickname
Returns

path to the zip file

def is_downloaded(self, dataset_name: str) -> bool:
167    def is_downloaded(self, dataset_name: str) -> bool:
168        """
169        :param dataset_name: can be a dataset label or nickname
170        :type dataset_name: str
171        :return: True if the dataset is downloaded
172        """
173        info = self.get_dataset_info(dataset_name)
174        return info["tiff_sequence_path"] is not None
Parameters
  • dataset_name: can be a dataset label or nickname
Returns

True if the dataset is downloaded

def get_ZipTiffIterator( self, dataset_name: str, as_ndarray: bool = False) -> nanopyx.core.io.zip_image_loader.ZipTiffIterator:
176    def get_ZipTiffIterator(
177        self, dataset_name: str, as_ndarray: bool = False
178    ) -> ZipTiffIterator:
179        """
180        Downloads the tiff sequence and returns the ZipTiffIterator
181
182        :param dataset_name: can be a dataset label or nickname
183        :type dataset_name: str
184        :param as_ndarray: if True, returns a numpy array instead of a ZipTiffIterator
185        :type as_ndarray: bool
186        :return: ZipTiffIterator or numpy array
187        """
188        self._show_citation_notice(dataset_name)
189        file_path = self.download_tiff_sequence(dataset_name)
190        try:
191            zti = ZipTiffIterator(file_path)
192        except zipfile.BadZipFile:
193            self.clear_downloads()
194            # try once more
195            file_path = self.download_tiff_sequence(dataset_name)
196            zti = ZipTiffIterator(file_path)
197        if not as_ndarray:
198            return zti
199        else:
200            arr = np.asarray(zti)
201            zti.close()
202            return arr

Downloads the tiff sequence and returns the ZipTiffIterator

Parameters
  • dataset_name: can be a dataset label or nickname
  • as_ndarray: if True, returns a numpy array instead of a ZipTiffIterator
Returns

ZipTiffIterator or numpy array

def get_thumbnail(self, dataset_name: str) -> str:
204    def get_thumbnail(self, dataset_name: str) -> str:
205        """
206        Returns the path to the thumbnail
207
208        :param dataset_name: can be a dataset label or nickname
209        :type dataset_name: str
210        :return: path to the thumbnail
211        """
212        info = self.get_dataset_info(dataset_name)
213        return info["thumbnail_path"]

Returns the path to the thumbnail

Parameters
  • dataset_name: can be a dataset label or nickname
Returns

path to the thumbnail

def clear_downloads(self):
215    def clear_downloads(self):
216        """
217        Deletes all downloaded datasets
218        """
219        if os.path.exists(self._temp_dir):
220            shutil.rmtree(self._temp_dir)

Deletes all downloaded datasets